/*
 * MemoryController class holds Registers shared by all Memory Interfaces.
 * Memory operations should be invoked through the MemoryController.
 * */

package cpu.components;

import java.util.Formatter;

import system.memory.RAM;
import cpu.datastores.*;
import cpu.datatypes.Word;
import cpu.interfaces.EventListener;

public class MemoryUnit {
	// Memory Address Register
	public Register16 MAR;
	
	// Memory Buffer Register
	public Register16 MBR;
	public boolean caching=false;
	// The memory bank
	private RAM ram;
	
	public CacheUnit cacheunit; 
	
	private cpu.components.CPU cpu;
	
	public MemoryUnit( cpu.components.CPU cpu ) {
		this.cpu = cpu;

		cacheunit=new CacheUnit( this);

		
		MAR = new Register16( );
		MBR = new Register16( );
		ram = new RAM( this, cacheunit );
	}
	
	// get a word from memory
	public void get( ) {
		ram.get( );
		
		cpu.controlunit.updateMemoryAddressIndicator();
		cpu.controlunit.updateMemoryBufferIndicator();
		cpu.controlunit.updateCacheAddressIndicator();
		cpu.controlunit.updateCacheBufferIndicator();

	}
	// put a word to memory
	public void put( ) {
		ram.put( );
		
		cpu.controlunit.updateMemoryAddressIndicator();
		cpu.controlunit.updateMemoryBufferIndicator();
		cpu.controlunit.updateCacheAddressIndicator();
		cpu.controlunit.updateCacheBufferIndicator();
	}
	
	// dump memory to system console for debugging.  
	// Same utility can be written programmatically in a trap function.
	public void dump() {
		Formatter fmt = new Formatter();

		for( int i = 0; i < 4096; i = i + 2 ) {
			
			for( int j = 0; j < 8; j++ ) {
				MAR.fromSignedInteger( i + j * 4096 );
				get( );

				fmt.format("%10s:%6s", MAR.toSignedInteger( ), MBR.toSignedInteger( ) );
				
			}
			fmt.format("\n" );
		}
		System.out.println( fmt.toString() );
	}
}
